#ifndef __UTIL__CURVE_HPP__
#define __UTIL__CURVE_HPP__

#include <string>
#include <vector>
#include "cache_strategy.hpp"
#include "constrained_value.hpp"
#include "point.hpp"

namespace util {
  /** @brief Curve utility class.

      The curve class encapsulates b-spline curves sepcified in the
      VLAB formats.  Currently versions are supported (original, cver
      1 1 and 1.4).

      @todo Add support for cver 1 2
      @todo Add support for cver 1 3
  */
  class curve {
  public:
    curve();
    curve(std::string filename, util::cache_strategy strategy = all, unsigned int samples = 1000, double error = 0.001);
    curve(const curve& c);

    util::point operator()(double t) const;

    double length(double a, double b) const;
    double travel(double t, double l) const;

    util::point tangent(double t) const;
    util::point normal(double t) const;

  private:
    void reread();
    void reset_cache();

    util::point eval(util::d01 t) const;
    double basis0(double t) const;
    double basis1(double t) const;
    double basis2(double t) const;
    double basis3(double t) const;

    std::string    filename;
    cache_strategy strategy;
    unsigned int   samples;
    double         error;

    std::vector<util::point> control_points;
    mutable std::vector<std::pair<bool, util::point> > cache;

    bool closed;
  };
}

#endif
